package lumis.service.wsrp.producer;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import lumis.service.wsrp.common.WSRPUtils;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.GenericGenerator;

import com.sun.portal.wsrp.common.LeaseTime;
import com.sun.portal.wsrp.common.stubs.v2.RegistrationData;
import com.sun.portal.wsrp.producer.Producer;
import com.sun.portal.wsrp.producer.registration.RegistrationRecord;

/**
 * Entity representing the Registration made by a consumer on the producer.
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
@Entity
@Table(name="lum_WsrpPRegistrationData")
@SuppressWarnings("serial")
@GenericGenerator(name = "portal-guid", strategy = "lumis.portal.dao.hibernate.GuidGenerator")
class RemoteConsumerRegistration implements Serializable 
{
    @Id
	@GeneratedValue(generator = "portal-guid")
    private String registrationHandle;
    
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="producerId")
    private ProducerImpl producer;
	
    private String consumerName;
    
    private String consumerAgent;
    
    private boolean methodGetSupported;
    
    private boolean enabled;
    
    private String consumerModes;
    
    private String consumerWindowStates;
    
    private String consumerUserScopes;
    
    private String customUserProfileData;
    
    private Date lifetimeTerminationTime;
    
    @OneToMany(mappedBy="registration", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<ClonedPortlet> clonedPortlets = new HashSet<ClonedPortlet>();
       
    /**
     * Returns the consumer name of the associated consumer.
     * @param consumerName associated to this registration.
     */
    public void setConsumerName(String cName)
    {
        this.consumerName = cName;
    }
        
    /**
     * Sets the registrationHandle for this registration.
     * @param regHandle associated to this registration.
     */
    public void setRegistrationHandle(String regHandle)
    {
        this.registrationHandle = regHandle;
    }
    
    /**
     * Set consumer Agent of the associated consumer.
     * @param consumerAgent associated to this registration. 
     */
    public void setConsumerAgent(String cAgent)
    {
        this.consumerAgent = cAgent;
    }
    
    /**
     * Sets if consumer has implemented portlet URLs in a manner that supports HTML markup containing 
     * forms with method="get".
     * @param true if consumer has implements forms with get method, otherwise, false should be passed.
     */
    public void setMethodGetSupported(boolean val)
    {
        this.methodGetSupported = val;
    }
    
    /**
     * Sets the portlet modes the consumer is willing to render.
     * @param cModes the portlet modes separated by commas.
     */
    public void setConsumerModes(String cModes)
    {
        this.consumerModes = cModes;
    }
    
    /**
     * Set the consumer window states the consumer is willing to render. 
     * @param val the windows states separated by commas.
     */
    public void setConsumerWindowStates(String val)
    {
        this.consumerWindowStates = val;
    }
    
    /**
     * Sets the consumer user scopes.  Currently unused.
     * @param val user scopes separated by commas.
     */
    public void setConsumerUserScopes(String val)
    {
        this.consumerUserScopes = val;
    }
    
    /**
     * Sets the consumer user profile data.  Currently unused.
     * @param profileData custom user profile data.
     */
    public void setCustomUserProfileData(String profileData)
    {
        this.customUserProfileData = profileData;
    }
    
    /**
     * Sets the producer associated with the registartion.
     * @param pKey producerKey of the to be procuder associated.
     */
    public void setProducer(Producer producer)  
    {
		this.producer = (ProducerImpl) producer;
    }
    
    /**
     * Returns the consumer name associated to this registration.
     * @return consumer name associated to this registration.
     */
    public String getConsumerName()
    {
        return this.consumerName;
    }
    
    /**
     * Returns the registration handle for current registration.
     * @return registrationHandle for current registration.
     */
    public String getRegistrationHandle()
    {
        return this.registrationHandle;
    }
    
    /**
     * Returns consumer agent for the current registration.
     * @return consumerAgendt for the current registration.
     */
    public String getConsumerAgent()
    {
        return this.consumerAgent;
    }
    
    /**
     * Returns if consumer has implemented portlet URLs {@link RemoteConsumerRegistration#setMethodGetSupported(boolean)}.
     * @return true if GET method was implemented for forms.
     */
    public boolean getMethodGetSupported()
    {
        return this.methodGetSupported;
    }

    /**
     * Returns the portlet modes the consumer is willing to render.
     * @return portlet modes the consumer is willing to render separated by commas.
     */
    public String getConsumerModes()
    {
        return this.consumerModes;
    }
    
    /**
     * Returns the window states the consumer is willing to render.
     * @return window states the consumer is willing to render separated by commas.
     */
    public String getConsumerWindowStates()
    {
        return this.consumerWindowStates;
    }
    
    /**
     * Returns the user scopes.
     * @return user scopes.
     */
    public String getConsumerUserScopes()
    {
        return this.consumerUserScopes;
    }
    
    /**
     * Returns the custom user profile data.
     * @return customUserProfileData associated to the registration.
     */
    public String getCustomUserProfileData()
    {
        return this.customUserProfileData;
    }
    
    /**
     * Returns the producerKey associated with the registration.
     * @return producerKey which this registration is associated to. 
     */
    public String getProducerKey()
    {
        return this.producer.getProducerKey();
    }

    /**
     * Returns the producer associated with the registration.
     * @return producer which this registration is associated to. 
     */
    public ProducerImpl getProducer()
    {
    	return this.producer;
    }

    /**
     * Returns the lifetime termination date.
     * @return lifetime of the current registration.
     */
    public Date getLifetimeTerminationTime() 
    {
        return lifetimeTerminationTime;
    }

    /**
     * Sets the lifetime termination date.
     * @param lifetimeTerminationTime for the current registration.
     */
    public void setLifetimeTerminationTime(Date lifetimeTerminationTime) 
    {
        this.lifetimeTerminationTime = lifetimeTerminationTime;
    }  

	/**
	 * Returns if the registration is enabled.
	 * @return true is the registration is enabled, false otherwise.
	 */
	public boolean isEnabled() 
	{
		return enabled;
	}

	/**
	 * Set the registration status.
	 * @param enabled the status to set.
	 */
	public void setEnabled(boolean enabled) 
	{
		this.enabled = enabled;
	}
	
	/**
	 * Returns the registrationData for this registration.
	 * @return registrationData for this registration.
	 */
	public RegistrationData getRegistrationData()
	{
		RegistrationData registrationData = new RegistrationData();
		registrationData.setConsumerAgent(this.getConsumerAgent());
		registrationData.setConsumerName(this.getConsumerName());
		registrationData.setMethodGetSupported(this.methodGetSupported);
		return registrationData;
	}
	
	/**
	 * Set the registrationData for this registration.
	 * @param registrationData for this registration.
	 */
	public void setRegistrationData(RegistrationData registrationData)
	{
		this.consumerAgent = registrationData.getConsumerAgent();
		this.consumerName = registrationData.getConsumerName();
		this.methodGetSupported = registrationData.isMethodGetSupported();
	}
	
	/**
	 * Returns the registrationRecord for this registration.
	 * @return registrationRecord for this registration.
	 */
	public RegistrationRecord getRegistrationRecord()
	{
		RegistrationRecord registrationRecord = new RegistrationRecord(this.registrationHandle, this.enabled, getRegistrationData(), getLifetime());
		return registrationRecord;
	}
	
	/**
	 * Sets the registration record for this registration.
	 * @param registrationRecord for this registration.
	 */
	public void setRegistrationRecord(RegistrationRecord registrationRecord )
	{
		setRegistrationData(registrationRecord.getRegistrationData());
		setLifetime(registrationRecord.getLifetime());
		this.enabled = registrationRecord.isEnabled();
	}
	
	/**
	 * Returns the lifetime for this registration.
	 * @param lifetime associated to the registration.
	 */
	public void setLifetime(LeaseTime lifetime)
	{
		this.lifetimeTerminationTime = WSRPUtils.dateFromXMLGregorianCalendar(lifetime.getTerminationTime());
	}
	
	/**
	 * Gets the lifetime for this registration.
	 * @return lifetime leaseTime associated to the current registration.
	 */
	public LeaseTime getLifetime()
	{
		LeaseTime lifetime = null;
		if(this.lifetimeTerminationTime != null)
		{
			lifetime = new LeaseTime();
			lifetime.setTerminationTime(WSRPUtils.toXMLGregorianCalendar(this.lifetimeTerminationTime));
			lifetime.setCurrentTime(WSRPUtils.toXMLGregorianCalendar(System.currentTimeMillis()));
		}
		return lifetime;
	}

	/**
	 * Returns the portlets that have been cloned during this registration.
	 * @return clonedPortlets associated to the registration. 
	 */
	public Collection<ClonedPortlet> getClonedPortlets() 
	{
		return clonedPortlets;
	}

	/**
	 * Set the portlets that need to be/have been cloned during this registration.
	 * @param clonedPortlets the clonedPortlets to set.
	 */
	public void setClonedPortlets(Collection<ClonedPortlet> clonedPortlets) 
	{
		this.clonedPortlets = new HashSet<ClonedPortlet>(clonedPortlets);
	}
}
